package com.wk.springbootlearn.common.aop;

import com.wk.springbootlearn.pojo.constant.CodeConstant;
import com.wk.springbootlearn.pojo.constant.MsgConstant;
import com.wk.springbootlearn.common.model.CommonLog;
import com.wk.springbootlearn.common.model.Response;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.exception.ExceptionUtils;
import org.springframework.validation.BindException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import org.springframework.web.servlet.NoHandlerFoundException;

import javax.servlet.http.HttpServletRequest;
import java.util.Arrays;

//全局异常处理
@Slf4j
@RestControllerAdvice
public class GlobalExceptionHandler {

    // 处理运行异常
    @ExceptionHandler(RuntimeException.class)
    public Response handleRuntimeException(HttpServletRequest request, RuntimeException exception) {
        String errDetail = exception.getMessage();
        String method = request.getMethod();
        String requestURI = request.getRequestURI();
        String stackTrace = ExceptionUtils.getStackTrace(exception);
        String logInfo = new CommonLog().setHttpMethod(method).setUrl(requestURI).setErrorCode(CodeConstant.SERVER_ERROR).setErrorMsg(MsgConstant.SERVER_FAIL).setErrorDetail(errDetail).setErrorTrace(stackTrace).toString();
        log.error(logInfo);
        return new Response().setErr(errDetail)
                .setMsg(MsgConstant.SERVER_FAIL);
    }

    // 捕获404，400这种无法到达controller的错误
    @ExceptionHandler(value = Exception.class)
    public Response defaultErrorHandler(HttpServletRequest request, Exception exception) {
        String errDetail = exception.getMessage();
        String method = request.getMethod();
        String requestURI = request.getRequestURI();
        int code;
        String msg;
        String stackTrace = ExceptionUtils.getStackTrace(exception);
        if (exception instanceof NoHandlerFoundException) {
            code = CodeConstant.NOT_FOUND;
            msg = MsgConstant.NOT_FOUND_FAIL;
        } else if (exception instanceof BindException) {
            code = CodeConstant.PARAMS_VALID_ERROR;
            msg = MsgConstant.PARAMS_VALID_FAIL;
        } else {
            code = CodeConstant.SERVER_ERROR;
            msg = MsgConstant.FAIL;
        }
        String logInfo = new CommonLog().setHttpMethod(method).setUrl(requestURI).setErrorCode(code).setErrorMsg(msg).setErrorDetail(errDetail).setErrorTrace(stackTrace).toString();
        log.error(logInfo);
        return new Response().setErr(errDetail)
                .setCode(code)
                .setMsg(msg);
    }
}
